package org.snia.cdmi.model;

import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;

public class AccessControlList implements Serializable {
    private static final long serialVersionUID = 8095040648034788376L;

    private HashSet<Grant> grants = new HashSet<Grant>();
    private String owner = null;

    public String getAccessKey() {
        return owner;
    }

    public void setAccessKey(String owner) {
        this.owner = owner;
    }

    public void grantPermission(Grantee grantee, Permission permission) {
        grants.add(new Grant(grantee, permission));
    }

    public void grantAllPermissions(Grant... grantsVarArg) {
        for (Grant gap : grantsVarArg) {
            grantPermission(gap.getGrantee(), gap.getPermission());
        }
    }

    public void revokeAllPermissions(Grantee grantee) {
        ArrayList<Grant> grantsToRemove = new ArrayList<Grant>();
        for (Grant gap : grants) {
            if (gap.getGrantee().equals(grantee)) {
                grantsToRemove.add(gap);
            }
        }
        grants.removeAll(grantsToRemove);
    }

    public Set<Grant> getGrants() {
        return grants;
    }
    
    @Override
	public String toString() {
        return "AccessControlList [owner=" + owner + ", grants=" + getGrants() + "]";
    }

	public void fromJson(byte[] acl) {
		JsonFactory f = new JsonFactory();
		try {
			JsonParser jp = f.createJsonParser(acl);
			@SuppressWarnings("unused")
			JsonToken tolkein = jp.nextToken();//START_OBJECT
			while ((tolkein = jp.nextToken()) != JsonToken.END_OBJECT) {
				String key = jp.getCurrentName();
				if ("acl".equals(key)) {//process acl
					tolkein = jp.nextToken();
					while ((tolkein = jp.nextToken()) != JsonToken.END_OBJECT) {
						key = jp.getCurrentName();
						tolkein = jp.nextToken();
						String value = jp.getText();
						System.out.println("   Key = " + key + " : Value = " + value);
						this.grants.add(new Grant(new KeyGrantee(key), Permission.fromValue(value)));
						//jp.nextToken();
					}//while	
				} else {
					//忽略
				}
			}
		} catch (JsonParseException e) {
			e.printStackTrace();//忽略
		} catch (IOException e) {
			e.printStackTrace();//忽略
		}
	}
	
	public String toJson(String extowner) {
		StringWriter outBuffer = new StringWriter();
		try {
			JsonFactory f = new JsonFactory();
			JsonGenerator g = f.createJsonGenerator(outBuffer);
			g.useDefaultPrettyPrinter();
			g.writeStartObject();

//			g.writeStringField("objectID", objectID);
//
//			g.writeStringField("capabilitiesURI", capabilitiesURI);
//			g.writeStringField("domainURI", domainURI);
			g.writeStringField("owner", extowner);
			g.writeObjectFieldStart("metadata");
	        for (Grant gap : grants) {
	            g.writeStringField(gap.getGrantee().getIdentifier(), gap.getPermission().toString());
	        }
	        g.writeEndObject(); 
			g.writeEndObject();
			g.flush();
		} catch (Exception ex) {
			ex.printStackTrace();
			return ("Error : " + ex);
		}
		//
		return outBuffer.toString();
	}
}
